const Router = require("koa-router");
const router = new Router();
const KoaConfig = require("../../../koaconfig");
const multer = require("@koa/multer");
const path = require("path");
const { hashPassword } = require("../../utils/bcryptTool");
const fs = require("fs");
const {
  addComment,
  addArticleCommentReply,
  deleteArticleComment,
  deleteArticleCommentReply,
  getArticleDetail,
} = require("../../db/DBApi/ArticleApi");
const {
  updataAuthorInfo,
  getAuthorInfoById,
  updataAuthorAvatar,
  followAuthor,
  unfollowAuthor,
  addCollectFolder,
  deleteCollectFolder,
  addArticleToCollectFolder,
  deleteArticleFromCollectFolder,
  deleteAuthor,
  getAuthorArticleList,
} = require("../../db/DBApi/AuthorApi");
const { getDraftList } = require("../../db/DBApi/DraftApi");
const {
  verifyToken,
  getLongToken,
  getShortToken,
} = require("../../utils/tokenTool");

router.prefix(KoaConfig.path.private);

// 获取用户详细信息，获取用户自己的信息，包括用户名、邮箱、头像、个人简介等
router.get("/getAuthorDetailInfo", verifyToken, async (ctx, next) => {
  // 从token中获取用户的email
  const email = ctx.state.user.email;

  // 调用数据库API，获取用户信息
  const res = await getAuthorInfoById(email);

  // 获取用户信息失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "获取用户信息失败",
    };
    return;
  }

  // 对返回的作者的信息进行处理
  // 构建新的收藏夹列表
  const collectionFolders = await Promise.all(
    res.collectList.map(async (folder) => {
      const collectItems = await Promise.all(
        folder.collectItem.map(async (itemId) => {
          const article = await getArticleDetail(itemId);
          if (article) {
            return {
              title: article.title,
              _id: article._id,
              summary: article.summary,
            };
          }
          return null;
        })
      );

      return {
        folderName: folder.folderName,
        collectItem: collectItems.filter((item) => item !== null),
      };
    })
  );

  res.collectList = collectionFolders;

  // 获取用户信息成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: res,
  };
});

// 修改用户信息，主要是修改用户名、邮箱、头像、个人简介等
// 这里暂时实现了修改昵称，密码还有个人简介的功能，其他的功能后续再添加
router.post("/modifyUserInfo", verifyToken, async (ctx, next) => {
  // 前端传递的参数
  let { nickname, password, description } = ctx.request.body;

  // 从token中获取用户的email
  const email = ctx.state.user.email;

  // 查看作者是否存在
  const author = await getAuthorInfoById(email);

  // 作者不存在
  if (!author) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "修改失败，作者不存在",
    };
  }

  // 密码加密
  let hashedPassword = "";
  if (password) {
    hashedPassword = await hashPassword(password);
  }

  // 调用数据库API，修改用户信息
  const res = await updataAuthorInfo(email, {
    nickname,
    password: hashedPassword,
    description,
  });

  // 修改用户信息失败
  // 在这里进行了修改，进过测试才发现，如果作者只是修改了部分的信息，比如密码，那么这里的res会返回false，导致修改失败
  // 所以这里将这个接口进行了修改，只有作者不存在的时候才会修改失败
  // if (!res) {
  //   ctx.status = 500;
  //   ctx.body = {
  //     code: 500,
  //     message: "修改用户信息失败",
  //   };
  //   return;
  // }

  // 修改用户信息成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "修改用户信息成功",
  };
});

// 用户注销，删除用户信息，将用户状态设置为注销状态，不可登录
router.post("/deleteUser", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 调用数据库API，删除用户信息
  const res = await deleteAuthor(email);

  // 删除用户信息失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "删除用户信息失败",
    };
    return;
  }

  // 将作者的文件夹给删除
  const authorFolder = path.join(__dirname, "../../../public/author", email);

  fs.rmSync(authorFolder, { recursive: true, force: true });

  // 删除用户信息成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "删除用户信息成功",
  };
});

// 用户添加评论
router.post("/addComment", verifyToken, async (ctx, next) => {
  // 前端传递的参数
  const { articleId, content, createTime } = ctx.request.body;

  // 从token中获取用户的email
  const authorEmail = ctx.state.user.email;

  // 调用数据库API，添加评论
  const res = await addComment(articleId, authorEmail, {
    content,
    createTime: createTime || new Date(),
  });

  console.log("评论的文章结果，", res);

  // 评论添加失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "评论添加失败",
    };
    return;
  }

  // 评论添加成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: res.commentList,
  };
});

// 用户删除评论
router.delete("/deleteComment", verifyToken, async (ctx, next) => {
  // 前端传递的参数
  const { articleId, commentId } = ctx.request.query;

  // 从token中获取用户的email
  // 删除者的email
  const authorEmail = ctx.state.user.email;

  // 调用数据库API，删除评论
  const res = await deleteArticleComment(articleId, commentId, authorEmail);

  // 删除评论失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "删除评论失败",
    };
    return;
  }

  // 删除评论成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "删除评论成功",
  };
});

// 用户回复评论
router.post("/addCommentReply", verifyToken, async (ctx, next) => {
  // 前端传递的参数
  const { articleId, commentId, createTime, content } = ctx.request.body;

  // 从token中获取用户的email
  const authorEmail = ctx.state.user.email;

  // 调用数据库API，添加评论
  const res = await addArticleCommentReply(articleId, commentId, authorEmail, {
    content: content,
    createTime: createTime || new Date(),
  });

  // 评论回复失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "评论回复失败",
    };
    return;
  }

  // 评论回复成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: res.commentList.filter(
      (item) => item._id.toString() === commentId.toString()
    )[0],
  };
});

// 用户删除评论的回复
router.delete("/deleteCommentReply", verifyToken, async (ctx, next) => {
  // 前端传递的参数
  const { articleId, commentId, replyId } = ctx.request.query;

  // 从token中获取用户的email
  // 删除者的email
  const authorEmail = ctx.state.user.email;

  // 调用数据库API，删除评论的回复
  const res = await deleteArticleCommentReply(
    articleId,
    commentId,
    replyId,
    authorEmail
  );

  // 删除评论的回复失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "删除评论的回复失败",
    };
    return;
  }

  // 删除评论的回复成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "删除评论的回复成功",
  };
});

// 上传文件存放路径、及文件命名
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    const email = req.user.email;
    console.log("file at 上传文件", file);
    cb(null, path.join(__dirname, "../../../public/author", email, "/avatar/"));
  },
  filename: function (req, file, cb) {
    cb(null, `${req.user.email}-${file.originalname}`); // 文件名加上时间戳
  },
});
//文件上传限制
const limits = {
  fields: 10, //非文件字段的数量
  fileSize: 2 * 1024 * 1024, //文件大小 单位 b
  files: 1, //文件数量
};
const upload = multer({ storage, limits });

// 用户上传头像
// 图片的目录结构是author/[authorEmail]/avatar/
// [authorEmail] 是作者的email
// 作者的文章图片目录结构author/[authorEmail]/articles/[articleId]/images/[imageName]
// [articleId] 是文章的id
router.post(
  "/uploadAvatar",
  verifyToken,
  upload.single("file"),
  async (ctx, next) => {
    // 前端传递的参数
    // 上传了作者的头像，还需要删除原来的头像
    // 从token中获取用户的email
    const email = ctx.state.user.email;

    // 获取用户原来的头像
    const author = await getAuthorInfoById(email);
    let oldAvatar = author.avatar;

    /* 
      这里发现了问题，就是上传文件的路径发生了变化，导致文件删除时发生了问题
    */

    // 删除用户原来的头像
    if (oldAvatar) {
      // http://localhost:3000/author/1234567890@qq.com/avatar/1234567890@qq.com-1b17af5b1590780a.jpg
      // 查找 'author/' 的位置
      const authorPos = oldAvatar.indexOf("/author/");

      // 如果找到了 'author/'，则从其后开始截取字符串
      if (authorPos !== -1) {
        // 截取 '/author/' 之后的部分
        oldAvatar = oldAvatar.substring(authorPos + "/author/".length);
      } else {
        // 如果没有找到 'author/'，则返回空字符串或其他默认值
        console.log("删除头像路径时失败了");
      }

      const oldAvatarPath = path.join(
        __dirname,
        "../../../public/author",
        oldAvatar
      );

      try {
        await fs.unlinkSync(oldAvatarPath);
      } catch (err) {
        console.error(err);
      }
    }

    const newAvatarPath = `http://${KoaConfig.host}:3000/author/${email}/avatar/${ctx.file.filename}`;

    // 更新用户头像地址
    const res = await updataAuthorAvatar(email, newAvatarPath);

    // 上传头像失败
    if (!res) {
      ctx.status = 500;
      ctx.body = {
        code: 500,
        message: "上传头像失败",
      };
      return;
    }

    // 上传头像成功
    ctx.status = 200;
    ctx.body = {
      code: 200,
      message: "上传头像成功",
      data: {
        avatar: newAvatarPath,
      },
    };
  }
);

// 用户关注作者
router.get("/subscribeAuthor", verifyToken, async (ctx, next) => {
  // 前端传递的参数
  const { authorEmail } = ctx.request.query;

  // 从token中获取用户的email
  const email = ctx.state.user.email;

  // 调用数据库API，关注作者
  const res = await followAuthor(email, authorEmail);

  // 关注作者失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "关注作者失败",
    };
    return;
  }

  // 关注作者成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "关注作者成功",
  };
});

// 用户取消关注作者
router.get("/unsubscribeAuthor", verifyToken, async (ctx, next) => {
  // 前端传递的参数
  const { authorEmail } = ctx.request.query;

  // 从token中获取用户的email
  const email = ctx.state.user.email;

  // 调用数据库API，取消关注作者
  const res = await unfollowAuthor(email, authorEmail);

  // 取消关注作者失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "取消关注作者失败",
    };
    return;
  }

  // 取消关注作者成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "取消关注作者成功",
  };
});

// 用户添加收藏夹
router.post("/addCollectionFolder", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 前端传递的参数
  const { folderName } = ctx.request.body;

  // 调用数据库API，添加收藏夹
  const res = await addCollectFolder(email, folderName);

  // 添加收藏夹失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "添加收藏夹失败",
    };
    return;
  }

  // 添加收藏夹成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "添加收藏夹成功",
  };
});

// 用户删除收藏夹
router.delete("/deleteCollectionFolder", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 前端传递的参数
  const { folderName } = ctx.request.query;

  // 调用数据库API，删除收藏夹
  const res = await deleteCollectFolder(email, folderName);

  // 删除收藏夹失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "删除收藏夹失败",
    };
    return;
  }

  // 删除收藏夹成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "删除收藏夹成功",
  };
});

// 用户向收藏夹中添加文章
// 注意这里用的api没有验证articleId是否存在，
router.post("/addArticleToCollectionFolder", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 前端传递的参数
  const { folderName, articleId } = ctx.request.body;

  // 验证文章是否存在
  const article = await getArticleDetail(articleId);
  if (!article) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "文章不存在",
    };
    return;
  }

  // 调用数据库API，向收藏夹中添加文章
  const res = await addArticleToCollectFolder(email, folderName, articleId);

  console.log("res at addArticleToCollectionFolder", res);

  // 向收藏夹中添加文章失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "向收藏夹中添加文章失败",
    };
    return;
  }

  // 向收藏夹中添加文章成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "向收藏夹中添加文章成功",
    data: res,
  };
});

// 用户从收藏夹中删除文章
router.delete(
  "/deleteArticleFromCollectionFolder",
  verifyToken,
  async (ctx, next) => {
    // 获取用户的email
    const email = ctx.state.user.email;

    // 前端传递的参数
    const { folderName, articleId } = ctx.request.query;

    console.log("folderName", folderName);
    console.log("articleId", articleId);
    console.log("body", ctx.request.body);

    // 调用数据库API，从收藏夹中删除文章
    const res = await deleteArticleFromCollectFolder(
      email,
      folderName,
      articleId
    );

    // 从收藏夹中删除文章失败
    if (!res) {
      ctx.status = 500;
      ctx.body = {
        code: 500,
        message: "从收藏夹中删除文章失败",
      };
      return;
    }

    // 从收藏夹中删除文章成功
    ctx.status = 200;
    ctx.body = {
      code: 200,
      message: "从收藏夹中删除文章成功",
    };
  }
);

// 获取用户的收藏夹列表
router.get("/getCollectionFolders", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 调用数据库API，获取用户的收藏夹列表
  const res = await getAuthorInfoById(email);

  // 获取用户的收藏夹列表失败
  if (!res) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "获取用户的收藏夹列表失败",
    };
    return;
  }

  // 对作者的收藏夹列表进行处理，只返回收藏夹的名称
  // const collectionFolders = res.collectList.map((item) => {
  //   return item.folderName;
  // });

  // 需求变更，返回收藏夹的名称，收藏夹的文章
  // 需求变更，返回收藏夹的名称，收藏夹的文章的标题和简介和_id

  // 构建新的收藏夹列表
  const collectionFolders = await Promise.all(
    res.collectList.map(async (folder) => {
      const collectItems = await Promise.all(
        folder.collectItem.map(async (itemId) => {
          const article = await getArticleDetail(itemId);
          if (article) {
            return {
              title: article.title,
              _id: article._id,
              summary: article.summary,
            };
          }
          return null;
        })
      );

      return {
        folderName: folder.folderName,
        collectItem: collectItems.filter((item) => item !== null),
      };
    })
  );

  // 获取用户的收藏夹列表成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: collectionFolders,
  };
});

// 获取用户对应的收藏夹的文章列表
router.get("/getCollectionFolderArticles", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 前端传递的参数
  const { folderName } = ctx.request.query;

  // 获取用户的收藏夹列表
  const author = await getAuthorInfoById(email);

  // 验证收藏夹是否存在
  const collectList = author.collectList;
  const collectFolder = collectList.find((item) => {
    return item.folderName === folderName;
  });
  if (!collectFolder) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "收藏夹不存在",
    };
    return;
  }

  // 遍历收藏夹的文章列表，获取文章的id
  const articleIdList = collectFolder.collectItem.map(async (item) => {
    const article = await getArticleDetail(item);
    // console.log(article._id);
    return {
      articleId: article._id,
      title: article.title,
      summary: article.summary,
      authorNickName: article.authorNickName,
      authorEmail: article.authorEmail,
      likes: article.likes,
      createTime: article.createTime,
      views: article.views,
      comments: article.commentList.length,
    };
  });

  // 等待所有文章的id都获取到
  const articleList = await Promise.all(articleIdList);

  // 获取用户对应的收藏夹的文章列表成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: articleList,
  };
});

// 获取用户的关注列表
router.get("/getFollowList", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 获取用户信息
  const author = await getAuthorInfoById(email);

  // 获取用户的关注列表
  let followResult = [];
  if (author.followers.length > 0) {
    followResult = author.followers.map(async (item) => {
      const followAuthor = await getAuthorInfoById(item);
      return {
        followerEmail: item,
        followerNickName: followAuthor.nickname,
        followerAvatar: followAuthor.avatar,
      };
    });
  }
  // 等待所有关注者的信息都获取到
  const followList = await Promise.all(followResult);

  // 获取用户的关注列表成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: followList,
  };
});

// 获取用户的粉丝列表
router.get("/getFansList", verifyToken, async (ctx, next) => {
  // 暂时未实现
  const email = ctx.state.user.email;

  // 获取用户信息
  const author = await getAuthorInfoById(email);

  // 获取用户的粉丝列表
  let fansResult = [];
  if (author.fans.length > 0) {
    fansResult = author.fans.map(async (item) => {
      const fansAuthor = await getAuthorInfoById(item);
      return {
        fansEmail: item,
        fansNickName: fansAuthor.nickname,
        fansAvatar: fansAuthor.avatar,
      };
    });
  }
  // 等待所有粉丝的信息都获取到
  const fansList = await Promise.all(fansResult);

  // 获取用户的粉丝列表成功
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: fansList,
  };
});

// 退出登录
router.get("/logout", verifyToken, async (ctx, next) => {
  // 退出登录，清除token
  // 前端需要清除token，后端需要返回token过期信息
  // 后端不需要做任何处理，前端根据返回信息清除token即可
  ctx.status = 200;
  ctx.body = {
    code: 200,
    message: "退出登录成功",
  };
});

// 作者获取文章列表
router.get("/getAuthorArticleList", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 获取作者信息
  const author = await getAuthorInfoById(email);

  // 判断作者是否存
  if (!author) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "作者不存在",
    };
    return;
  }

  // 获取作者文章列表ID
  // const articleList = author.articles;
  const articleList = await getAuthorArticleList(email);

  // 返回文章列表
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: articleList,
  };
});

// 作者获取草稿列表
router.get("/getAuthorDraftList", verifyToken, async (ctx, next) => {
  // 获取用户的email
  const email = ctx.state.user.email;

  // 获取作者信息
  const author = await getAuthorInfoById(email);

  // 判断作者是否存在
  if (!author) {
    ctx.status = 500;
    ctx.body = {
      code: 500,
      message: "作者不存在",
    };
    return;
  }

  // 获取作者草稿列表ID
  // const draftList = author.drafts;
  const draftList = await getDraftList(email);

  // 返回草稿列表
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: draftList,
  };
});

// 用户刷新 token
router.get("/refreshToken", verifyToken, async (ctx, next) => {
  // 刷新token，返回新的token
  // 前端用长 token 进行刷新
  // 如果可以走到这里就说明这里的长 token 有效

  // 获取用户的 email
  const email = ctx.state.user.email;

  // 获取短 token
  const shortToken = getShortToken({
    email: email,
  });
  // 获取长 token
  const longToken = getLongToken({
    email: email,
  });

  // 返回新的token
  ctx.status = 200;
  ctx.body = {
    code: 200,
    data: {
      shortToken,
      longToken,
    },
  };
});

module.exports = router;
